-
Notifications
You must be signed in to change notification settings - Fork 6k
Composite multiple layers in Windows software rendering #51759
Composite multiple layers in Windows software rendering #51759
Conversation
|
||
int width = x_max - x_min; | ||
int height = y_max - y_min; | ||
std::vector<uint32_t> allocation(width * height); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid this allocation if there's only 1 layer?
|
||
return view->PresentSoftwareBitmap( | ||
backing_store.allocation, backing_store.row_bytes, backing_store.height); | ||
int x_min = INT_MAX; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we split this up and have a helper for the compositing step?
// Overlay layer has pixel values: | ||
// RED: 127 WHITE: 0 | ||
// BLUE: 127 BLACK: 255 | ||
TEST_F(CompositorSoftwareTest, PresentMultiLayers) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we also have a test for layers that don't overlap fully?
Good idea. I'll get on that, thanks
…On Fri, Mar 29, 2024, 6:10 PM Loïc Sharma ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In shell/platform/windows/compositor_software_unittests.cc
<#51759 (comment)>:
> @@ -162,5 +162,57 @@ TEST_F(CompositorSoftwareTest, HeadlessPresentIgnored) {
ASSERT_TRUE(compositor.CollectBackingStore(&backing_store));
}
+// Test compositing an upper layer on a base layer, each 2x2 pixels.
+// Base layer has opaque pixel values:
+// BLACK RED
+// GREEN WHITE
+// Overlay layer has pixel values:
+// RED: 127 WHITE: 0
+// BLUE: 127 BLACK: 255
+TEST_F(CompositorSoftwareTest, PresentMultiLayers) {
Could we also have a test for layers that don't overlap fully?
—
Reply to this email directly, view it on GitHub
<#51759 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A2AOOLGAG435QHVIPVUGYB3Y2XRGHAVCNFSM6AAAAABFNLUONOVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMYTSNRZGY2DQNJXGE>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
I think so. I'll break it up a bit
…On Fri, Mar 29, 2024, 6:09 PM Loïc Sharma ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In shell/platform/windows/compositor_software.cc
<#51759 (comment)>:
> @@ -51,18 +51,77 @@ bool CompositorSoftware::Present(FlutterViewId view_id,
return view->ClearSoftwareBitmap();
}
- // TODO: Support compositing layers and platform views.
- // See: flutter/flutter#31713
- FML_DCHECK(layers_count == 1);
- FML_DCHECK(layers[0]->offset.x == 0 && layers[0]->offset.y == 0);
- FML_DCHECK(layers[0]->type == kFlutterLayerContentTypeBackingStore);
- FML_DCHECK(layers[0]->backing_store->type ==
- kFlutterBackingStoreTypeSoftware);
-
- const auto& backing_store = layers[0]->backing_store->software;
-
- return view->PresentSoftwareBitmap(
- backing_store.allocation, backing_store.row_bytes, backing_store.height);
+ int x_min = INT_MAX;
Could we split this up and have a helper for the compositing step?
—
Reply to this email directly, view it on GitHub
<#51759 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A2AOOLAG3AJ6BSSHTALG2WDY2XRABAVCNFSM6AAAAABFNLUONOVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMYTSNRZGY2DOOBQG4>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
May need some extra logic once we implement platform views but yeah I think
it's doable like that
…On Fri, Mar 29, 2024, 6:07 PM Loïc Sharma ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In shell/platform/windows/compositor_software.cc
<#51759 (comment)>:
> + int x_max = INT_MIN;
+ int y_min = INT_MAX;
+ int y_max = INT_MIN;
+ for (const FlutterLayer** layer = layers; layer < layers + layers_count;
+ layer++) {
+ auto& offset = (*layer)->offset;
+ auto& size = (*layer)->size;
+ x_min = std::min(x_min, static_cast<int>(offset.x));
+ y_min = std::min(y_min, static_cast<int>(offset.y));
+ x_max = std::max(x_max, static_cast<int>(offset.x + size.width));
+ y_max = std::max(y_max, static_cast<int>(offset.y + size.height));
+ }
+
+ int width = x_max - x_min;
+ int height = y_max - y_min;
+ std::vector<uint32_t> allocation(width * height);
Can we avoid this allocation if there's just a single layer?
—
Reply to this email directly, view it on GitHub
<#51759 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A2AOOLC3IPZGCTJ6OB6PBYTY2XQZ5AVCNFSM6AAAAABFNLUONOVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMYTSNRZGY2DKNJYGY>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good - just a few comments!
auto& offset = layer.offset; | ||
auto& size = layer.size; | ||
|
||
for (int y_src = 0; y_src < size.height; y_src++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will take a closer look, but first thoughts:
- but it feels like it should be possible to update the loop conditions to avoid the two < 0, >= height checks below.
- this feels like there should be a way to parallelise this a bit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose the obvious way to parallelize this would be to use the GPU, but this is the software compositor, so that seems self defeating.
Also, I will test adjusting the loop statements once it rebuilds.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to check now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect the right way to parallelize would be to vectorize this code if possible... I wonder if Windows has any helpers that can do efficient bitmap blending? If not, that seems like too much work for an MVP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only ones I'm familiar with work with HDCs instead of pixel data in memory, and so we would need to create those new DCs per layer to apply them as far as I understand
int x_min = INT_MAX; | ||
int x_max = INT_MIN; | ||
int y_min = INT_MAX; | ||
int y_max = INT_MIN; | ||
for (const FlutterLayer** layer = layers; layer < layers + layers_count; | ||
layer++) { | ||
const FlutterPoint& offset = (*layer)->offset; | ||
const FlutterSize& size = (*layer)->size; | ||
// FlutterPoint and FlutterSize store coordinates as doubles. | ||
// Coordinates must be truncated to integers to represent whole pixels. | ||
x_min = std::min(x_min, static_cast<int>(offset.x)); | ||
y_min = std::min(y_min, static_cast<int>(offset.y)); | ||
x_max = std::max(x_max, static_cast<int>(offset.x + size.width)); | ||
y_max = std::max(y_max, static_cast<int>(offset.y + size.height)); | ||
} | ||
|
||
int width = x_max - x_min; | ||
int height = y_max - y_min; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add a helper for the logic to calculate the position/size of the present?
width * 4, height); | ||
} | ||
|
||
void CompositorSoftware::BlendLayer(std::vector<uint32_t>& allocation, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of an instance method that's declared in the header, should we make this be a top-level function in an anonymous namespace in this file?
In my mind the header file is best for public APIs or methods that need to interact with instance fields. However, this helper is self-contained logic that doesn't require any instance members.
return view->PresentSoftwareBitmap( | ||
backing_store.allocation, backing_store.row_bytes, backing_store.height); | ||
return view->PresentSoftwareBitmap(static_cast<void*>(allocation.data()), | ||
width * 4, height); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For someone not familiar with the bitmap allocation, this 4
might look like a magic value. Could we add a constant for the 4 with a quick comment for clarity?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, excellent work!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…146645) flutter/engine@d8560d4...98a8ad1 2024-04-11 [email protected] [et] Correctly plumb usage line length limit (flutter/engine#52039) 2024-04-11 [email protected] Revert "Roll Dart SDK from 3d13dbfb3284 to 764bdb7d0344 (1 revision) (#52051)" (flutter/engine#52060) 2024-04-11 [email protected] Composite multiple layers in Windows software rendering (flutter/engine#51759) 2024-04-11 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Roll Dart SDK from 764bdb7d0344 to 0219e897c6ac (1 revision) (#52053)" (flutter/engine#52058) 2024-04-11 [email protected] Roll Skia from 2a2fe4303507 to 1dc3c2c1b550 (1 revision) (flutter/engine#52055) 2024-04-11 [email protected] Roll Skia from aa30d76a345f to 2a2fe4303507 (1 revision) (flutter/engine#52054) 2024-04-11 [email protected] Roll Dart SDK from 764bdb7d0344 to 0219e897c6ac (1 revision) (flutter/engine#52053) 2024-04-11 [email protected] Roll Skia from 29f0c9d84e70 to aa30d76a345f (1 revision) (flutter/engine#52052) 2024-04-11 [email protected] Roll Dart SDK from 3d13dbfb3284 to 764bdb7d0344 (1 revision) (flutter/engine#52051) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…lutter#146645) flutter/engine@d8560d4...98a8ad1 2024-04-11 [email protected] [et] Correctly plumb usage line length limit (flutter/engine#52039) 2024-04-11 [email protected] Revert "Roll Dart SDK from 3d13dbfb3284 to 764bdb7d0344 (1 revision) (flutter#52051)" (flutter/engine#52060) 2024-04-11 [email protected] Composite multiple layers in Windows software rendering (flutter/engine#51759) 2024-04-11 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Roll Dart SDK from 764bdb7d0344 to 0219e897c6ac (1 revision) (flutter#52053)" (flutter/engine#52058) 2024-04-11 [email protected] Roll Skia from 2a2fe4303507 to 1dc3c2c1b550 (1 revision) (flutter/engine#52055) 2024-04-11 [email protected] Roll Skia from aa30d76a345f to 2a2fe4303507 (1 revision) (flutter/engine#52054) 2024-04-11 [email protected] Roll Dart SDK from 764bdb7d0344 to 0219e897c6ac (1 revision) (flutter/engine#52053) 2024-04-11 [email protected] Roll Skia from 29f0c9d84e70 to aa30d76a345f (1 revision) (flutter/engine#52052) 2024-04-11 [email protected] Roll Dart SDK from 3d13dbfb3284 to 764bdb7d0344 (1 revision) (flutter/engine#52051) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Blend pixels per-alpha when presenting multiple layers from the software compositor.
Part of flutter/flutter#143375
Pre-launch Checklist
///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.